package org.dromara.web.controller;


import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.AlipaySignature;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.java.service.partnerpayments.app.model.Transaction;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.dao.business.domain.MerchantPayment;
import org.dromara.web.plugins.alipay.AlipayService;
import org.dromara.web.plugins.weixin.WeixinPayService;
import org.dromara.web.service.plugins.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


@Slf4j
@Controller
@RequestMapping("/payment")
public class PaymentNotifyController {


    @Autowired
    WeixinPayService weixinPayService;
    @Autowired
    PaymentService paymentService;
    @Autowired
    AlipayService alipayService;




    @SaIgnore
    @PostMapping("/wechat_notify")
    public void wechatNotify(HttpServletRequest request, HttpServletResponse response) {

        String characterEncoding = request.getCharacterEncoding();

        //从请求头获取验签字段
        String timeStamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String signature = request.getHeader("Wechatpay-Signature");
        String wechatPaySerial = request.getHeader("Wechatpay-Serial");

        log.info("wx callback params,timesStamp:{},nonce:{},signature:{},certSn:{}", timeStamp, nonce, signature, wechatPaySerial);
        try(BufferedReader reader = new BufferedReader(new
            InputStreamReader(request.getInputStream()))) {
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            String body = sb.toString();

            Transaction notification = weixinPayService.callbackSignVerify(body, nonce, timeStamp, signature, wechatPaySerial);

            String outBatchNo = notification.getOutTradeNo();
//            String batchStatus = res.getString("batch_status");
            //处理相关业务
            paymentService.paymentCallback(outBatchNo, Transaction.TradeStateEnum.SUCCESS.equals(notification.getTradeState()));

            //响应微信服务器
            response.setStatus(200);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "SUCCESS");
            jsonObject.put("message", "SUCCESS");
            response.getOutputStream().write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
            response.flushBuffer();
        } catch (Exception e) {
            log.error("wx callback error", e);
            response.setStatus(500);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "ERROR");
            jsonObject.put("message", "签名失败");
            try {
                response.getOutputStream().write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
                response.flushBuffer();
            } catch (Exception ex) {
                log.error("微信回调失败",e);
            }
        }
    }


    @SaIgnore
    @PostMapping("/alipay_notify")
    public void apipayNotify(HttpServletRequest request, HttpServletResponse response) {
        Map< String , String > params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for(Iterator iter = requestParams.keySet().iterator(); iter.hasNext();){
            String name = (String)iter.next();
            String[] values = (String [])requestParams.get(name);
            String valueStr = "";
            for(int i = 0;i < values.length;i ++ ){
                valueStr =  (i==values.length-1)?valueStr + values [i]:valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put (name,valueStr);
        }
        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean flag = alipayService.verifyNotifyParam(params);
        if (flag) {
            String outTradeNo = request.getParameter("out_trade_no");
            String tradeStatus = request.getParameter("trade_status");
            paymentService.paymentCallback(outTradeNo, "TRADE_SUCCESS".equals(tradeStatus));
        }
    }


    @ResponseBody
    @GetMapping("/status")
    public R<MerchantPayment> paymentStatus(Long paymentId) {
        return R.ok(paymentService.paymentDetail(paymentId));
    }
}
